home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 2 / Amiga Tools 2.iso / tools / mg / src.lzh / amiga / tty.c < prev    next >
C/C++ Source or Header  |  1990-05-23  |  11KB  |  498 lines

  1. /*
  2.  * Name:    MG 2a Amiga console device virtual terminal display Last
  3.  * Edit:    29-Nov-87 mic@emx.cc.utexas.edu Created:    19-Apr-86
  4.  * mic@emx.cc.utexas.edu
  5.  * 
  6.  * Drives the Amiga console device display.  The code is basically like the
  7.  * termcap driver in that it uses the console device scrolling region.  It
  8.  * also has some hacks to manage the console device colors.  The latest hack
  9.  * is to inform the terminal I/O driver when we intend to do an escape
  10.  * sequence; this allows the terminal I/O driver to turn off the cursor
  11.  * without breaking up the sequences, leading to a garbled screen.
  12.  */
  13.  
  14. #undef    MANX
  15. #undef    LATTICE
  16. #include "compiler.h"
  17. #include "change_color.h"
  18. #include "mode_fg.h"
  19. #include "mode_bg.h"
  20. #include "mode_rendition.h"
  21. #include "text_fg.h"
  22. #include "text_bg.h"
  23. #include "text_rendition.h"
  24.  
  25. #include <exec/types.h>
  26. #include <exec/nodes.h>
  27. #include <exec/lists.h>
  28. #include <exec/tasks.h>
  29. #include <exec/ports.h>
  30. #include <exec/io.h>
  31. #include <devices/console.h>
  32. #include <libraries/dos.h>
  33. #include <graphics/clip.h>
  34. #include <graphics/view.h>
  35. #include <graphics/rastport.h>
  36. #include <graphics/layers.h>
  37. #include <graphics/text.h>
  38. #include <graphics/gfxbase.h>
  39. #ifndef    MANX
  40. #include <intuition/intuitionbase.h>
  41. #endif
  42. #include <intuition/intuition.h>
  43.  
  44. #undef    TRUE
  45. #undef    FALSE
  46. #include    "def.h"
  47.  
  48. #ifdef    ANSI
  49. #include <stdlib.h>
  50. #endif
  51.  
  52. #define    BEL    0x07        /* BEL character.         */
  53. #define    ESC    0x1B        /* ESC character.         */
  54. #define    LF    0x0A        /* Linefeed character         */
  55. #define    CSI    0x9B        /* Command Sequence Introducer     */
  56.  
  57. extern int      ttrow;
  58. extern int      ttcol;
  59. extern int      tttop;
  60. extern int      ttbot;
  61. extern int      tthue;
  62.  
  63. int             tceeol = 3;    /* Costs, ANSI display.         */
  64. int             tcinsl = 17;
  65. int             tcdell = 16;
  66.  
  67.  
  68. #ifdef    CHANGE_COLOR
  69. short           mode_rendition = MODE_RENDITION,    /* set standard colors */
  70.                 text_rendition = TEXT_RENDITION, text_fg = TEXT_FG + 30, text_bg = TEXT_BG + 40, mode_fg = MODE_FG + 30, mode_bg = MODE_BG + 40;
  71. #else                /* colors are hard-coded         */
  72. #define mode_rendition MODE_RENDITION
  73. #define    text_rendition TEXT_RENDITION
  74. #define text_fg (TEXT_FG + 30)
  75. #define text_bg (TEXT_BG + 40)
  76. #define mode_fg (MODE_FG + 30)
  77. #define mode_bg (MODE_BG + 40)
  78. #endif
  79.  
  80. #ifdef    LATTICE_50
  81. static char     a;
  82. #endif
  83.  
  84. #ifdef    LATTICE
  85. VOID 
  86. asciiparm(int);
  87. #else
  88. VOID 
  89. asciiparm();
  90. #endif
  91. VOID 
  92. ttnowindow();
  93. VOID 
  94. ttwindow();
  95.  
  96. /*
  97.  * Initialize the terminal when the editor Initialize the virtual terminal.
  98.  * Set the console device's top edge below the front-to-back gadgets, to
  99.  * avoid garbage when scrolling.
  100.  */
  101. VOID
  102. ttinit()
  103. {
  104.     ttputc(CSI);
  105.     asciiparm(TOP_OFFSET);
  106.     ttputc('y');
  107. }
  108.  
  109. /*
  110.  * Clean up the terminal, in anticipation of a return to the command
  111.  * interpreter. This is a no-op on the Amiga, since the window is deleted
  112.  * anyway.
  113.  */
  114. VOID
  115. tttidy()
  116. {
  117. }
  118.  
  119. /*
  120.  * Move the cursor to the specified origin 0 row and column position. Try to
  121.  * optimize out extra moves; redisplay may have left the cursor in the right
  122.  * location last time!
  123.  */
  124. VOID
  125. ttmove(row, col)
  126. {
  127.     if (ttrow != row || ttcol != col) {
  128.         ttnflush(8);    /* flush if buffer too full      */
  129.         ttputc(CSI);
  130.         asciiparm(row + 1);
  131.         ttputc(';');
  132.         asciiparm(col + 1);
  133.         ttputc('H');
  134.         ttrow = row;
  135.         ttcol = col;
  136.     }
  137. }
  138.  
  139. /*
  140.  * Erase to end of line.
  141.  */
  142. VOID
  143. tteeol()
  144. {
  145.     ttnflush(2);        /* flush if not enough room to fit in buffer */
  146.     ttputc(CSI);
  147.     ttputc('K');
  148. }
  149.  
  150. /*
  151.  * Erase to end of page.
  152.  */
  153. VOID
  154. tteeop()
  155. {
  156.     ttnflush(12);        /* flush (but only if not enough room for seq */
  157.     ttputc(CSI);
  158.     asciiparm((tthue == CTEXT) ? text_rendition : mode_rendition);
  159.     ttputc(';');
  160.     asciiparm(text_fg);
  161.     ttputc(';');
  162.     asciiparm(text_bg);
  163.     ttputc('m');
  164.     ttputc(CSI);        /* clear to end of display */
  165.     ttputc('J');
  166. }
  167.  
  168. /*
  169.  * Make a noise.
  170.  */
  171. VOID
  172. ttbeep()
  173. {
  174.     ttputc(BEL);
  175.     ttflush();
  176. }
  177.  
  178. /*
  179.  * Convert a number to decimal ascii, and write it out. Used to deal with
  180.  * numeric arguments.
  181.  */
  182. VOID
  183. asciiparm(n)
  184.     register int    n;
  185. {
  186.     if (n > 9)
  187.         asciiparm(n / 10);
  188.     ttputc((unsigned char) ((n % 10) + '0'));
  189. }
  190.  
  191. /*
  192.  * Insert a block of blank lines onto the screen, using a scrolling region
  193.  * that starts at row "row" and extends down to row "bot".  Deal with the one
  194.  * line case, which is a little bit special, with special case code.
  195.  */
  196. VOID
  197. ttinsl(row, bot, nchunk)
  198. {
  199.     if (row == bot) {    /* Funny case.         */
  200.         if (nchunk != 1)
  201.             panic("ttinsl: nchunk != 1");
  202.         ttmove(row, 0);
  203.         tteeol();
  204.         return;
  205.     }
  206.     ttmove(1 + bot - nchunk, 0);
  207.     if (nchunk > 0) {
  208.         ttwindow(row, bot);
  209.         ttnflush(4);    /* don't break the sequence  */
  210.         ttputc(CSI);
  211.         asciiparm(nchunk);
  212.         ttputc('T');    /* Scroll scrolling region down     */
  213.         ttnowindow();
  214.     }
  215. }
  216.  
  217. /*
  218.  * Delete a block of lines, with the uppermost line at row "row", in a screen
  219.  * slice that extends to row "bot". The "nchunk" is the number of lines that
  220.  * have to be deleted.  It's really easy with the console device scrolling
  221.  * region.
  222.  */
  223. VOID
  224. ttdell(row, bot, nchunk)
  225. {
  226.     if (row == bot) {    /* One line special case     */
  227.         ttmove(row, 0);
  228.         tteeol();
  229.         return;
  230.     }
  231.     if (nchunk > 0) {
  232.         ttwindow(row, bot);
  233.         ttnflush(4);    /* don't break esc. sequence     */
  234.         ttputc(CSI);
  235.         asciiparm(nchunk);
  236.         ttputc('S');    /* Scroll scrolling region up     */
  237.         ttnowindow();
  238.     }
  239.     ttrow = HUGE;
  240.     ttcol = HUGE;
  241.     ttmove(bot - nchunk, 0);
  242. }
  243.  
  244. /*
  245.  * This routine sets the scrolling window on the display to go from line
  246.  * "top" to line "bot" (origin 0, inclusive). The caller checks for the
  247.  * pathalogical 1 line scroll window that doesn't work right on all systems,
  248.  * and avoids it. The "ttrow" and "ttcol" variables are set to a crazy value
  249.  * to ensure that ttmove() actually does something.
  250.  */
  251.  
  252. extern struct Window *EmW;    /* The window MG uses */
  253.  
  254. VOID
  255. ttwindow(top, bot)
  256. {
  257.     if (tttop != top || ttbot != bot) {
  258.         ttnflush(10);    /* Flush if necessary     */
  259.         ttputc(CSI);    /* Home cursor         */
  260.         ttputc('H');
  261.  
  262.         ttputc(CSI);    /* Set top offset     */
  263.         asciiparm(TOP_OFFSET + top * FontHeight(EmW));
  264.         ttputc('y');
  265.  
  266.         ttputc(CSI);
  267.         asciiparm(bot - top + 1);    /* Set page length     */
  268.         ttputc('t');
  269.  
  270.         ttrow = HUGE;    /* Force cursor reset     */
  271.         ttcol = HUGE;
  272.         tttop = top;    /* Save region state     */
  273.         ttbot = bot;
  274.     }
  275. }
  276.  
  277. /*
  278.  * Switch to full screen scrolling
  279.  */
  280. VOID
  281. ttnowindow()
  282. {
  283.     ttnflush(10);        /* Flush if necessary         */
  284.     ttputc(CSI);        /* Home cursor             */
  285.     ttputc('H');
  286.  
  287.     ttputc(CSI);        /* Set top offset to normal     */
  288.     asciiparm(TOP_OFFSET);
  289.     ttputc('y');
  290.  
  291.     ttputc(CSI);        /* Set page length to nrow     */
  292.     asciiparm(nrow);
  293.     ttputc('t');
  294.  
  295.     ttrow = HUGE;        /* Make cursor unknown.         */
  296.     ttcol = HUGE;
  297.     tttop = HUGE;
  298.     ttbot = HUGE;
  299. }
  300.  
  301. #ifdef    CHANGE_COLOR
  302. /*
  303.  * Set the rendition of the mode line by selecting colors from the following:
  304.  * 0 -- plain text 1 -- bold-face 3 -- italic 4 -- underscore 7 -- inverse
  305.  * video Certain of these selections may be less than appealing :-)
  306.  */
  307.  
  308. ttmode(f, n)
  309. {
  310.     register int    s;
  311.     char            buf[2];
  312.  
  313.     if (!(f & FFARG)) {
  314.         if ((s = ereply("Set mode line rendition (0-7): ",
  315.                 buf, sizeof(buf))) != TRUE)
  316.             return (s);
  317.         n = atoi(buf);
  318.     }
  319.     if (n < 0 || n > 7)
  320.         return (FALSE);
  321.  
  322.     mode_rendition = n;    /* store the color     */
  323.     sgarbf = TRUE;
  324.     return (TRUE);
  325. }
  326.  
  327. /*
  328.  * Set the rendition of the text area. Most of these selections will be less
  329.  * than appealing :-]
  330.  */
  331.  
  332. tttext(f, n)
  333. {
  334.     register int    s;
  335.     char            buf[2];
  336.  
  337.     if (!(f & FFARG)) {
  338.         if ((s = ereply("Set text rendition (0-7): ",
  339.                 buf, sizeof(buf))) != TRUE)
  340.             return (s);
  341.         n = atoi(buf);
  342.     }
  343.     if (n < 0 || n > 7)
  344.         return (FALSE);
  345.  
  346.     text_rendition = n;    /* store the color     */
  347.     sgarbf = TRUE;
  348.     return (TRUE);
  349. }
  350.  
  351. /*
  352.  * Set foreground color for entire window to a value between 30 and 37, which
  353.  * corresponds to the arguments 0-7. This requires a total refresh, which
  354.  * sets up the screen.
  355.  */
  356.  
  357. textforeground(f, n)
  358. {
  359.     register int    s;
  360.     char            buf[2];
  361.  
  362.     if (!(f & FFARG)) {
  363.         if ((s = ereply("Text foreground color (0-7): ",
  364.                 buf, sizeof(buf))) != TRUE)
  365.             return (s);
  366.         n = atoi(buf);
  367.     }
  368.     if (n < 0 || n > 7)
  369.         return (FALSE);
  370.  
  371.     text_fg = n + 30;
  372.     sgarbf = TRUE;
  373.     return (TRUE);
  374. }
  375.  
  376. /*
  377.  * Set background color for entire window to a value between 40 and 47
  378.  * inclusive.
  379.  */
  380.  
  381. textbackground(f, n)
  382. {
  383.     register int    s;
  384.     char            buf[2];
  385.  
  386.     if (!(f & FFARG)) {
  387.         if ((s = ereply("Text background color (0-7): ",
  388.                 buf, sizeof(buf))) != TRUE)
  389.             return (s);
  390.         n = atoi(buf);
  391.     }
  392.     if (n < 0 || n > 7)
  393.         return (FALSE);
  394.  
  395.     text_bg = n + 40;
  396.     sgarbf = TRUE;
  397.     return (TRUE);
  398. }
  399.  
  400. /*
  401.  * Set foreground color for entire the mode line
  402.  */
  403.  
  404. modeforeground(f, n)
  405. {
  406.     register int    s;
  407.     char            buf[2];
  408.  
  409.     if (!(f & FFARG)) {
  410.         if ((s = ereply("Mode line foreground color (0-7): ",
  411.                 buf, sizeof(buf))) != TRUE)
  412.             return (s);
  413.         n = atoi(buf);
  414.     }
  415.     if (n < 0 || n > 7)
  416.         return (FALSE);
  417.  
  418.     mode_fg = n + 30;
  419.     sgarbf = TRUE;
  420.     return (TRUE);
  421. }
  422.  
  423. /*
  424.  * Set background color for the mode line
  425.  */
  426.  
  427. modebackground(f, n)
  428. {
  429.     register int    s;
  430.     char            buf[2];
  431.  
  432.     if (!(f & FFARG)) {
  433.         if ((s = ereply("Mode line background color (0-7): ",
  434.                 buf, sizeof(buf))) != TRUE)
  435.             return (s);
  436.         n = atoi(buf);
  437.     }
  438.     if (n < 0 || n > 7)
  439.         return (FALSE);
  440.  
  441.     mode_bg = n + 40;
  442.     sgarbf = TRUE;
  443.     return (TRUE);
  444. }
  445. #endif
  446.  
  447. /*
  448.  * Set the current writing color to the specified color. Watch for color
  449.  * changes that are not going to do anything (the color is already right) and
  450.  * don't send anything to the display.
  451.  */
  452.  
  453. VOID
  454. ttcolor(color)
  455.     register int    color;
  456. {
  457.     if (color != tthue) {
  458.         ttnflush(12);    /* Flush if necessary     */
  459.         if (color == CTEXT) {    /* Normal video.     */
  460.             ttputc(CSI);    /* Reset to 0         */
  461.             ttputc('m');
  462.             ttputc(CSI);    /* Set text style     */
  463.             asciiparm(text_rendition);
  464.             ttputc(';');
  465.             asciiparm(text_fg);
  466.             ttputc(';');
  467.             asciiparm(text_bg);
  468.             ttputc('m');
  469.         } else if (color == CMODE) {    /* Standout mode     */
  470.             ttputc(CSI);    /* Reset to 0         */
  471.             ttputc('m');
  472.             ttputc(CSI);    /* Set standout mode     */
  473.             asciiparm(mode_rendition);
  474.             ttputc(';');
  475.             asciiparm(mode_fg);    /* Use mode line colors     */
  476.             ttputc(';');
  477.             asciiparm(mode_bg);
  478.             ttputc('m');
  479.         }
  480.         tthue = color;    /* Save the color.     */
  481.     }
  482. }
  483.  
  484. /*
  485.  * This routine is called by the "refresh the screen" command to try and
  486.  * resize the display. The new size, which must be deadstopped to not exceed
  487.  * the NROW and NCOL limits, is stored back into "nrow" and "ncol". Display
  488.  * can always deal with a screen NROW by NCOL. Look in "window.c" to see how
  489.  * the caller deals with a change. On the Amiga, we make the Intuition
  490.  * terminal driver do all the work.
  491.  */
  492.  
  493. VOID
  494. ttresize()
  495. {
  496.     setttysize();
  497. }
  498.